package com.guigu.eduservice.util;

import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.guigu.eduservice.config.AliPayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 支付宝沙箱支付工具类
 * 作用：封装所有与支付宝交互的核心逻辑，对外提供简单接口
 */
@Component // 交给Spring管理，方便注入配置
public class AlipaySandboxUtil {

    // 支付宝客户端（全局唯一，初始化一次即可）
    private static AlipayClient alipayClient;

    // 注入配置类（获取沙箱参数）
    @Autowired
    private AliPayConfig aliPayConfig;

    /**
     * 初始化支付宝客户端
     * @PostConstruct：项目启动时自动执行，初始化客户端
     */
    @PostConstruct
    public void init() {
        try {
            // 创建客户端实例（参数从配置类获取）
            alipayClient = new DefaultAlipayClient(
                    AliPayConfig.GATEWAY_URL,       // 沙箱网关
                    aliPayConfig.getAppId(),        // APPID
                    aliPayConfig.getAppPrivateKey(),// 应用私钥
                    AliPayConfig.FORMAT,            // 数据格式
                    AliPayConfig.CHARSET,           // 编码
                    aliPayConfig.getAlipayPublicKey(),// 支付宝公钥
                    AliPayConfig.SIGN_TYPE          // 签名方式
            );
            System.out.println("支付宝沙箱客户端初始化成功");
        } catch (Exception e) {
            System.err.println("支付宝沙箱客户端初始化失败：" + e.getMessage());
            // 初始化失败时抛异常，防止后续调用出错
            throw new RuntimeException("支付宝客户端初始化失败，请检查配置");
        }
    }

    /**
     * 生成支付表单（用于前端跳转支付）
     * @param outTradeNo 商户订单号（自己系统的订单ID）
     * @param totalAmount 支付金额（单位：元，如0.01）
     * @param subject 订单标题（如"车辆定金"）
     * @return 支付表单HTML字符串
     */
    public String createPayForm(String outTradeNo, String totalAmount, String subject) {
        try {
            // 1. 参数校验
            if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
                throw new RuntimeException("订单号不能为空");
            }
            if (totalAmount == null || totalAmount.trim().isEmpty()) {
                throw new RuntimeException("支付金额不能为空");
            }
            if (subject == null || subject.trim().isEmpty()) {
                throw new RuntimeException("订单标题不能为空");
            }
            if (!totalAmount.matches("^\\d+(\\.\\d{2})?$")) {
                throw new RuntimeException("支付金额格式错误，必须保留2位小数");
            }

            // 2. 使用支付宝官方模型类构建业务参数（推荐方式，无序列化问题）
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.setOutTradeNo(outTradeNo);      // 订单号（带前缀）
            model.setTotalAmount(totalAmount);     // 支付金额（保留2位小数）
            model.setSubject(subject);             // 订单标题
            model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 固定值（即时到账）
            // 可选：添加超时时间（避免订单过期导致的校验失败）
            model.setTimeoutExpress("30m"); // 30分钟超时

            // 3. 构建支付请求
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.setNotifyUrl(aliPayConfig.getNotifyUrl());
            request.setReturnUrl(aliPayConfig.getReturnUrl());
            request.setBizModel(model); // 直接设置模型类，无需手动序列化

            // 4. 调用支付宝接口
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            if (response.isSuccess()) {
                System.out.println("支付表单生成成功：" + response.getBody().substring(0, 100) + "...");
                return response.getBody();
            } else {
                throw new RuntimeException("生成支付表单失败：" + response.getMsg() + "，错误码：" + response.getCode());
            }
        } catch (AlipayApiException e) {
            System.err.println("支付宝接口调用异常：" + e.getMessage() + "，错误码：" + e.getErrCode());
            throw new RuntimeException("支付宝接口调用失败");
        }
    }


    /**
     * 验证支付宝回调签名
     * @param params 回调参数（从request中获取）
     * @return 签名是否有效（true=有效）
     */
    public boolean verifySign(Map<String, String> params) {
        try {
            // 调用支付宝工具类验证签名
            return AlipaySignature.rsaCheckV1(
                    params,
                    aliPayConfig.getAlipayPublicKey(),
                    AliPayConfig.CHARSET,
                    AliPayConfig.SIGN_TYPE
            );
        } catch (AlipayApiException e) {
            System.err.println("签名验证失败：" + e.getMessage());
            return false;
        }
    }

    /**
     * 查询订单支付状态
     * @param outTradeNo 商户订单号
     * @return 支付状态（如"TRADE_SUCCESS"表示支付成功）
     */
    public String queryOrderStatus(String outTradeNo) {
        try {
            // 创建查询请求对象
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            // 构建查询参数
            JSONObject bizContent = new JSONObject();
            bizContent.set("out_trade_no", outTradeNo); // 商户订单号
            request.setBizContent(bizContent.toString());

            // 调用查询接口
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                return response.getTradeStatus(); // 返回支付状态
            } else {
                System.err.println("查询订单失败：" + response.getMsg());
                return null;
            }
        } catch (AlipayApiException e) {
            System.err.println("查询订单异常：" + e.getMessage());
            return null;
        }
    }
}